import socket
import struct
import threading

import cv2
import numpy


def get_host_ip():
    try:
        s_t = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s_t.connect(('8.8.8.8', 80))
        ip = s_t.getsockname()[0]
    finally:
        s_t.close()
    return ip

def get_distance():
    ip = get_host_ip()
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 绑定端口:
    print(ip)
    s.bind((ip, 8801))
    print('距离获取8801')
    while True:
        # 接收数据:
        data, addr = s.recvfrom(2048)
        print('Received from %s' % data)
        s.sendto(b'Hello, %s!' % data, addr)

def get_camera():
    ip = get_host_ip()
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 绑定端口:
    print(ip)
    s.bind((ip, 8802))
    print('视频画面8802')
    while True:
        data, address = s.recvfrom(65535)  # 先接收的是字节长度
        if len(data) != 4:  # 进行简单的校验长度值是int类型占四个字节
            length = 0
        else:
            length = struct.unpack('i', data)[0]  # 长度值
        data, address = s.recvfrom(65535)  # 接收编码图像数据
        if length != len(data):  # 进行简单的校验
            continue
        data = numpy.array(bytearray(data))  # 格式转换
        imgdecode = cv2.imdecode(data, 1)  # 解码
        print('have received one frame')
        cv2.imshow('frames', imgdecode)  # 窗口显示
        if cv2.waitKey(1) == 27:  # 按下“ESC”退出
            break
    s.close()
    cv2.destroyAllWindows()

def send_ctrl():
    host = '192.168.1.100'
    port = 8803
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 建立连接:
    s.connect((host, port))
    print('控制8803')
    # 接收欢迎消息:
    print(s.recv(1024).decode('utf-8'))
    for data in [b'Michael', b'Tracy', b'Sarah']:
        # 发送数据:
        s.send(data)
        print(s.recv(1024).decode('utf-8'))
    s.send(b'exit')
    s.close()

if __name__ == '__main__':
    t_distance = threading.Thread(target=get_distance, name='LoopThread')
    t_distance.start()

    t_camera = threading.Thread(target=get_camera, name='LoopThread1')
    t_camera.start()

    t_ctrl = threading.Thread(target=send_ctrl, name='LoopThread2')
    t_ctrl.start()
